package com.zmn.oms.business.impl.callpop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.common.data.common.constant.TagConsts;
import com.zmn.base.common.data.common.dro.tags.TagsDRO;
import com.zmn.base.remind.common.enums.ScenesTypeEnum;
import com.zmn.base.remind.common.enums.record.RecordByeWayEnum;
import com.zmn.base.remind.common.model.record.BizRecordDRO;
import com.zmn.base.remind.dubbo.interfaces.record.RecordListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.MethodSignUtils;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.http.HttpUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.framework.core.http.HttpClientsFactory;
import com.zmn.manager.common.cat.http.MonitorHttpsUtils;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.callpop.CallRecordBService;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.work.masterwork.MasterWorkBService;
import com.zmn.oms.business.interfaces.work.tag.OrderTagBService;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.OrderTagConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.MobileUtil;
import com.zmn.oms.common.utils.TimeUtils;
import com.zmn.oms.model.dto.log.CallRecordLogDTO;
import com.zmn.oms.model.dto.tag.OrderTagAddDTO;
import com.zmn.oms.model.dto.work.masterwork.ContactUserDTO;
import com.zmn.oms.model.entity.callrecord.OrderCallRecord;
import com.zmn.oms.model.entity.tag.OrderTag;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.call.CallRecordVO;
import com.zmn.oms.model.vo.call.CallRecords;
import com.zmn.oms.model.vo.work.RemindRecordsVO;
import com.zmn.oms.services.interfaces.callrecord.OrderCallRecordService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.xno.common.enums.FinishState;
import com.zmn.xno.common.enums.FinishType;
import com.zmn.xno.dubbo.interfaces.call.CallRecordQueryRemoteService;
import com.zmn.xno.dubbo.model.call.CallRecordDRO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 类描述：通话记录实现
 *
 * @author lujia
 * @date 2019/02/19 16:03
 */
@Service
@Slf4j
public class CallRecordBServiceImpl implements CallRecordBService {

    @Resource
    private OrderCallRecordService orderCallRecordService;
    @Resource
    private MasterWorkBService masterWorkBService;
    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private OrderTagBService orderTagBService;
    @Autowired
    private OrderTagService orderTagService;
    @Autowired
    private BaseCodeService baseCodeService;
    @Autowired
    private OrderWorkService orderWorkService;

    public final static int BASE_CODE_MAP_ONE_TYPE_MINIMUM_EFFECTIVE_CALL_TIME = 1102;

    /**
     * 通话记录接口
     */
    private static final String CALL_RECORD_URL = "http://calltape.zmnoa.com:8888/calltape.php?trsondin=1619443434365626164343431&tel=%s&time_m=%s&time_t=%s";

    /**
     * 录音地址前缀，后缀
     */
    private static final String RECORD_URL_PREFIX = "http://calltape.zmnoa.com:9999/";
    private static final String RECORD_URL_SUFFIX = ".mp3";

    /**
     * 新呼叫系统录音地址
     */
    @Value("${call.record.url:http://dev-cc.xiujiadian.com/record/call/list}")
    String NEW_CALL_RECORD_URL;

    /**
     * 催单通话记录地址
     */
    @Value("${call.remind.record.url:http://192.168.99.6:13343/remind/listByBizId}")
    String REMIND_CALL_RECORD_URL;

    /**
     * 根据呼叫ID查询通话记录
     */
    @Value("${call.record.id.url:http://dev-cc.xiujiadian.com/open/record/call/%s}")
    String CALL_RECORD_QUERY_URL;

    /**
     * 根据orderId查询通话记录
     */
    @Value("${call.order.record.url:http://dev-cc.xiujiadian.com/open/record/callout/%s/%s}")
    String ORDER_CALL_RECORD_QUERY_URL;

    /**
     * 呼叫系统密钥
     */
    @Value("${call.info.sign.key:867D0B5FBEBFEF9818DF9F39E87EAA9E}")
    String SIGN_KEY;

    /**
     * 提取通话记录正则
     */
    private static final Pattern CALL_RECORD_PATTERN = Pattern.compile("\\{[^{}]*\\}");

    @Reference(version = com.zmn.xno.common.constant.SystemConstants.DUBBO_CONSTS_INTERFACE_VERSION, check = false)
    private CallRecordQueryRemoteService callRecordQueryRemoteService;
    @DubboReference(version = com.zmn.xno.common.constant.SystemConstants.DUBBO_CONSTS_INTERFACE_VERSION, check = false)
    private RecordListRemoteService recordListRemoteService;

    @Override
    public List<com.zmn.oms.model.vo.work.CallRecordVO> listXnoCallRecordByWorkId(Long workId) {
        List<com.zmn.oms.model.vo.work.CallRecordVO> callRecordVOList = Lists.newArrayList();
        // 小号通话记录，主动查询一次
        try {
            ResponseDTO<List<CallRecordDRO>> xnoListResponseDTO = callRecordQueryRemoteService.listByBizId(String.valueOf(workId));
            log.info("callRecord workId={}, xnoListResponseDTO：{}", workId, JSON.toJSONString(xnoListResponseDTO));
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(xnoListResponseDTO.getData())) {
                List<CallRecordDRO> callRecordDROList = xnoListResponseDTO.getData();
                callRecordDROList.forEach(item -> {
                    com.zmn.oms.model.vo.work.CallRecordVO orderCallVo = com.zmn.oms.model.vo.work.CallRecordVO.builder()
                            .callerNo(item.getCallNo()).bindId(item.getBindId())
                            .calledNo(item.getPeerNo()).callDuration(TimeUtils.getDate(item.getCallDuration()))
                            .startTime(item.getStartTime()).finishTime(item.getFinishTime())
                            .callRecordId(item.getCallId()).xnoNo(item.getXno())
                            .hangup(FinishType.of(item.getFinishType().toString()).getName())
                            .finishState(FinishState.of(String.valueOf(item.getFinishState())).getDesc())
                            .status(item.getCallStatus()).tapeUrl(item.getTapeUrl()).build();
                    if (Objects.equals(1, item.getProviderId())) {
                        // 移动，通话记录需要下载
                        orderCallVo.setType(2);
                    } else {
                        orderCallVo.setType(99);
                    }
                    callRecordVOList.add(orderCallVo);
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return callRecordVOList;
    }

    @Override
    public List<CallRecordVO> listCallRecordByPhone(String phone, Date startTime, Date endTime) {

        List<CallRecordVO> callRecordList = Lists.newArrayList();

        // 老系统通话记录
//        List<CallRecordVO> oldCallRecordList = getOldCallRecordByPhone(phone, startTime, endTime);
//        if (!CollectionUtils.isEmpty(oldCallRecordList)) {
//            callRecordList.addAll(oldCallRecordList);
//        }

        // 新系统通话记录
        List<CallRecordVO> newCallRecordList = getNewCallRecordByPhone(phone, startTime, endTime);
        if (!CollectionUtils.isEmpty(newCallRecordList)) {
            callRecordList.addAll(newCallRecordList);
        }

        callRecordList.forEach(item->{
            // 号码处理
            item.setPhone(MobileUtil.formatHideTel(item.getPhone()));
        });


        // 通话记录按时间倒序
        callRecordList.sort(Comparator.comparing(CallRecordVO::getCallTime).reversed());
        return callRecordList;
    }

    /**
     * 获取新系统通话记录
     * @param phone
     * @param startTime
     * @param endTime
     * @return
     */
    private List<CallRecordVO> getNewCallRecordByPhone(String phone, Date startTime, Date endTime) {

        String startDate = DateUtil.dateFormatToString(startTime, DateUtil.FORMAT_DEFAULT);
        String endDate = DateUtil.dateFormatToString(endTime, DateUtil.FORMAT_DEFAULT);

        Map<String, String> params = new HashMap<>(4);
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("phone", phone);
        params.put("sign", MethodSignUtils.sign(params, SIGN_KEY));

        try {

            log.debug("#call#pop# 新呼叫记录接口请求 {}, {}", NEW_CALL_RECORD_URL, JSON.toJSONString(params));
            String res = MonitorHttpsUtils.postForm(NEW_CALL_RECORD_URL, params);
            log.debug("#call#pop# 新呼叫记录接口响应 {}", res);

            if (StringUtil.isBlank(res)) {
                return Lists.newArrayList();
            }

            ResponseDTO<List<CallRecordVO>> responseDTO = JSON.parseObject(res, new TypeReference<ResponseDTO<List<CallRecordVO>>>(){});
            if (responseDTO.isSuccess()) {
                return responseDTO.getData();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return Lists.newArrayList();
    }

    /**
     * 老系统获取通话记录
     * @param phone
     * @param startTime
     * @param endTime
     * @return
     */
    private List<CallRecordVO> getOldCallRecordByPhone(String phone, Date startTime, Date endTime) {

        String startDate = DateUtil.dateFormatToString(startTime, DateUtil.FORMAT_DATE);
        String endDate = DateUtil.dateFormatToString(endTime, DateUtil.FORMAT_DATE);

        String url = String.format(CALL_RECORD_URL, phone, startDate, endDate);
        String res = HttpUtil.get(url);

        if (StringUtil.isBlank(res)) {
            return Lists.newArrayList();
        }

        List<String> callRecordList = Lists.newArrayList();
        Matcher matcher = CALL_RECORD_PATTERN.matcher(res);
        while (matcher.find()) {
            callRecordList.add(matcher.group());
        }

        return processCallRecordList(callRecordList);
    }

    /**
     * 处理通话记录
     * @param callRecordList
     * @return
     */
    private List<CallRecordVO> processCallRecordList(List<String> callRecordList){
        List<CallRecordVO> recordList = Lists.newArrayList();

        if (callRecordList.isEmpty()) {
            return recordList;
        }

        callRecordList.forEach(e -> {
            JSONObject jsonObject = JSON.parseObject(e);
            CallRecordVO record = new CallRecordVO();

            // 通话时间
            if (jsonObject.containsKey("1")) {
                record.setCallTime(jsonObject.getString("1"));
            }

            // 电话
            if (jsonObject.containsKey("2")) {
                record.setPhone(jsonObject.getString("2"));
            }

            // 城市
            if (jsonObject.containsKey("3")) {
                record.setCityName(jsonObject.getString("3"));
            }

            // 呼入呼出
            if (jsonObject.containsKey("4")) {
                boolean ring = Objects.equals(jsonObject.getString("4"), "RING");
                record.setCallInOut(ring ? "呼入" : "呼出");
            }

            // 话务员
            if (jsonObject.containsKey("0")) {
                record.setOperator(jsonObject.getString("0"));
            }

            // 渠道
            if (jsonObject.containsKey("5")) {
                record.setChannelName(jsonObject.getString("5"));
            }

            // 类型
            if (jsonObject.containsKey("label")) {
                record.setCallType(jsonObject.getString("label"));
            }

            // 录音
            if (jsonObject.containsKey("Recording")) {
                record.setSoundSrc(RECORD_URL_PREFIX + jsonObject.getString("Recording") + RECORD_URL_SUFFIX);
            }
            recordList.add(record);
        });
        return recordList;
    }

   /* public static void main(String[] args) throws Exception {

        Map<String, String> params = new HashMap<>(4);
        params.put("bizId", "10979215");
        params.put("sign", MethodSignUtils.sign(params, "867D0B5FBEBFEF9818DF9F39E87EAA9E"));
        String url = String.format("http://dev-cc.xiujiadian.com:10913/open/record/call/%s", 10979215);
        log.info("#call#pop# 新呼叫记录接口请求 {}, {}", url, JSON.toJSONString(params));
        String res = MonitorHttpsUtils.postForm(url, params);

        ResponseDTO<CallRecords> responseDTO = JSON.parseObject(res, new TypeReference<ResponseDTO<CallRecords>>() {
        });
        CallRecords callRecords = responseDTO.getData();
        OrderCallRecord orderCallRecord = OrderCallRecord.builder().callRecordId(10979215L).type(4).status(3)
                .startTime(callRecords.getMoStartTime())
                .finishTime(callRecords.getMoEndTime())
                .callDuration(callRecords.getMoDurationFormat())
                .hangup(callRecords.getByeUserString())
                .finishState("")
                .callerNo(callRecords.getFrom())
                .calledNo(callRecords.getTo())
                .tapeUrl(callRecords.getTapeUrl())
                .build();
        log.info("#call#pop# 新呼叫记录接口响应 {}", orderCallRecord);
    }*/

    /**
     * 工单小号通话记录格式化存储
     * @param callRecordLogDTO
     * @return
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_XNO_CALL_LOG)
    public void processXNORecordLog(CallRecordLogDTO callRecordLogDTO){

        // 保存通话记录
        OrderCallRecord orderCallRecord = BeanMapper.map(callRecordLogDTO, OrderCallRecord.class);
        log.info("工单小号通话记录格式化存储[{}]", JSONObject.toJSONString(orderCallRecord));
        orderCallRecordService.insertOrderCallRecord(orderCallRecord);
        // 更新联系用户时间
        ContactUserDTO contactUserDTO = new ContactUserDTO();
        contactUserDTO.setOrderId(callRecordLogDTO.getOrderId());
        contactUserDTO.setWorkId(callRecordLogDTO.getWorkId());
        contactUserDTO.setCallTime(callRecordLogDTO.getStartTime());
        masterWorkBService.updateContactTime(contactUserDTO);
    }

    /**
     * 工单小号通话结果日志
     *
     * @param callRecordLogDTO
     * @return
     */
    @Override
    public void processXnoContactTag(CallRecordLogDTO callRecordLogDTO) throws OmsBaseException {
        log.info("小号通话记录[{}]", JSONObject.toJSONString(callRecordLogDTO));
        if (Objects.isNull(callRecordLogDTO.getOrderId())) {
            return;
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(callRecordLogDTO.getOrderId(), callRecordLogDTO.getWorkId());
        if (orderWork == null) {
            return;
        }

        // 没有联系用户，不标记
        if (Objects.isNull(orderWork.getContactTime())) {
            return;
        }

        // 只有进行中的工单才标记是否有效通话
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            return;
        }

        // 工程师推荐，标记有效，这里不处理
        if (Objects.nonNull(orderWork.getRecommenderId()) &&
                Objects.equals(orderWork.getRecommenderType(), GlobalConsts.OPERATE_USER_TYPE_MASTER)
                && Objects.equals(orderWork.getRecommenderId().intValue(), orderWork.getMasterId())) {
            return;
        }

        if (callRecordLogDTO.getCallTime() == null) {
            log.info("无效的通话记录，没有开始时间，不处理 {}", JSON.toJSONString(callRecordLogDTO));
            return;
        }

        /*
         * 本需求三阶段写有效/无效字段。
         *  联系->通话记录->已完成/取消。派单-删除有效无效标签。
         * 1，本接口，只有 有小号的工单产生通话记录才能访问。故第二次写入。
         * 2，当工单以完成/已取消 时候，重新判断工单，写入无效联系。
         * 3， 判断是否有小号应该判断三个小号字段是否都为null。
         * 4， 记得判断重复打，通话无效->有效，通话有效->无效（X）。
         */

        // 出发之前需要先联系用户，如果通话开始时间如果大于上门时间，则是无效通话记录，不处理
        if (Objects.nonNull(orderWork.getVisitTime())) {
            if (callRecordLogDTO.getCallTime().getTime() >= orderWork.getVisitTime().getTime()) {
                return;
            }
        }

        // 工单已标记有效联系，不处理
        List<OrderTag> orderTags = orderTagService.listOrderTagByOrderId(callRecordLogDTO.getOrderId(), callRecordLogDTO.getWorkId());
        boolean isExist = orderTags.stream().anyMatch(m -> m.getTagId().equals(OrderTagConsts.TAG_ID_WORK_CONTACT_EFFECTIVE));
        if (isExist) {
            return;
        }

        // 通话时长配置
        TagsDRO oneBaseCodeMap = baseCodeService.getOneBaseCodeMap(com.zmn.consts.GlobalConsts.PLAT_MARK_ZMN,
                TagConsts.TAG_ONE_TYPE_MINIMUM_EFFECTIVE_CALL_TIME, null);
        Integer callDurationMin = Optional.ofNullable(oneBaseCodeMap.getTwoTypeId()).orElse(8);

        // 添加工单标记
        OrderTagAddDTO orderTagAddDTO = new OrderTagAddDTO();
        orderTagAddDTO.setOrderId(callRecordLogDTO.getOrderId());
        orderTagAddDTO.setWorkId(callRecordLogDTO.getWorkId());

        // 无效情况，呼出，未接通。 响铃时长 ≤ T，算无效联系
        if (Objects.equals(callRecordLogDTO.getStatus(), 1)
                && Optional.ofNullable(callRecordLogDTO.getCallSustainDuration()).orElse(0) < callDurationMin) {
            orderTagAddDTO.setTagIdList(Lists.newArrayList(OrderTagConsts.TAG_ID_WORK_CONTACT_INVALID));
        } else {
            // 其余情况皆为有效
            orderTagAddDTO.setTagIdList(Lists.newArrayList(OrderTagConsts.TAG_ID_WORK_CONTACT_EFFECTIVE));
            // 有效联系时间
            orderTagAddDTO.setContactTime(callRecordLogDTO.getCallTime());
            log.info("工单小号通话有效标记，参数{}",JSON.toJSONString(orderTagAddDTO));
        }

        orderTagBService.addOrderTag(orderTagAddDTO);
    }

    /**
     * 工单通话记录格式化存储
     * @param callRecordLogDTO
     * @return
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_CALL_LOG)
    public void processNormalRecordLog(CallRecordLogDTO callRecordLogDTO){

        // 保存通话记录
        OrderCallRecord orderCallRecord = OrderCallRecord.builder().orderId(callRecordLogDTO.getOrderId()).callDuration(callRecordLogDTO.getCallDuration()).type(1)
                .callerNo(callRecordLogDTO.getCallerNo()).calledNo(callRecordLogDTO.getCalledNo()).status(callRecordLogDTO.getStatus()).callType(1).calledType(2)
                .startTime(callRecordLogDTO.getStartTime()).finishTime(callRecordLogDTO.getFinishTime()).build();
        log.info("格式化存储普通通话记录:{}", JSONObject.toJSONString(orderCallRecord));
        orderCallRecordService.insertOrderCallRecord(orderCallRecord);
    }

    @Override
    public com.zmn.oms.model.vo.work.CallRecordVO getCallRecordFromCCByCallRecordId(String callRecordId){
        String url = String.format(CALL_RECORD_QUERY_URL, callRecordId);
        log.debug("CALL_RECORD_QUERY_URL={}, SIGN_KEY={}", CALL_RECORD_QUERY_URL, SIGN_KEY);
        Map<String, String> params = new HashMap<>(2);
        params.put("bizId", callRecordId);
        params.put("sign", MethodSignUtils.sign(params, SIGN_KEY));

        try {
            log.debug("#call# 查询通话记录接口请求 {}, {}", url, JSON.toJSONString(params));
            String res = MonitorHttpsUtils.postForm(url, params);
            log.debug("#call# 查询通话记录接口响应 {}", res);
            if (StringUtils.isBlank(res)) {
                return null;
            }

            ResponseDTO<CallRecords> responseDTO = JSON.parseObject(res, new TypeReference<ResponseDTO<CallRecords>>() {
            });

            CallRecords callRecords = responseDTO.getData();
            if (Objects.isNull(callRecords)) {
                return null;
            }

            com.zmn.oms.model.vo.work.CallRecordVO callRecordVO = com.zmn.oms.model.vo.work.CallRecordVO.builder()
                    .callRecordId(callRecordId)
                    .type(4).status(3)
                    .startTime(callRecords.getMoStartTime())
                    .finishTime(callRecords.getMoEndTime())
                    .callDuration(callRecords.getMoDurationFormat())
                    .hangup(callRecords.getByeUserString())
                    .finishState("")
                    .callerNo(callRecords.getFrom())
                    .calledNo(callRecords.getTo())
                    .tapeUrl(callRecords.getTapeUrl())
                    .build();

            return callRecordVO;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public List<com.zmn.oms.model.vo.work.CallRecordVO> getCallRecordFromCCByOrderId(String sysStr, Long orderId) {
        Objects.requireNonNull(orderId);
        Objects.requireNonNull(sysStr);
        String url = String.format(ORDER_CALL_RECORD_QUERY_URL, sysStr, orderId);
        Map<String, String> params = new HashMap<>(3);
        params.put("bizId", orderId.toString());
        params.put("bizType", sysStr);
        params.put("sign", MethodSignUtils.sign(params, SIGN_KEY));

        log.debug("{}接口 params={}", url, JSON.toJSONString(params));
        try {
            String res = MonitorHttpsUtils.postForm(url, params);
            log.debug("{}接口 result={}", url, res);
            if (StringUtil.isBlank(res)) {
                return null;
            }
            ResponseDTO<List<CallRecords>> responseDTO = JSON.parseObject(res, new TypeReference<ResponseDTO<List<CallRecords>>>() {
            });

            List<CallRecords> data = responseDTO.getData();
            if (CollectionUtil.isNullOrEmpty(data)) {
                return null;
            }

            List<com.zmn.oms.model.vo.work.CallRecordVO> callRecordVOList = new ArrayList<>(data.size());

            for (CallRecords callRecords : data) {
                com.zmn.oms.model.vo.work.CallRecordVO callRecordVO = com.zmn.oms.model.vo.work.CallRecordVO.builder()
                        .callRecordId(callRecords.getBizId())
                        .type(4).status(3)
                        .startTime(callRecords.getMoStartTime())
                        .finishTime(callRecords.getMoEndTime())
                        .callDuration(callRecords.getMoDurationFormat())
                        .hangup(callRecords.getByeUserString())
                        .finishState("")
                        .callerNo(callRecords.getFrom())
                        .calledNo(callRecords.getTo())
                        .tapeUrl(callRecords.getTapeUrl())
                        .build();
                callRecordVOList.add(callRecordVO);
            }

            return callRecordVOList;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }


        return null;
    }

    @Override
    public List<com.zmn.oms.model.vo.work.CallRecordVO> queryRemindRecords(Long orderId) {
        List<com.zmn.oms.model.vo.work.CallRecordVO> voList = Lists.newArrayList();
        voList.addAll(this.queryRemindRecordsFromOld(orderId));
        voList.addAll(this.queryRemindRecordsFromCC(orderId));
        return voList;
    }

    /**
     * 通过http接口获取催单通话记录 todo 暂时保留 之后base-remind系统稳定后会下线
     *
     * @param orderId
     */
    private List<com.zmn.oms.model.vo.work.CallRecordVO> queryRemindRecordsFromOld(Long orderId) {
        List<com.zmn.oms.model.vo.work.CallRecordVO> voList = Lists.newArrayList();
        List<String> list = Collections.singletonList(orderId.toString());
        Map<String, Object> dio = Maps.newHashMap();
        dio.put("data", JSON.parseArray(JSON.toJSONString(list)));
        String sign = MethodSignUtils.sign(dio, SIGN_KEY);
        dio.put("sign", sign);

        String json = JSON.toJSONString(dio);
        try {
            log.debug("催单电话通话记录请求：url:{}, json{}", REMIND_CALL_RECORD_URL, JSONObject.toJSONString(json));
            String result = HttpClientsFactory.getHttpClients().postJson(REMIND_CALL_RECORD_URL, json);
            log.debug("催单电话通话记录相应：{}", JSONObject.toJSONString(result));
            ResponseDTO<List<RemindRecordsVO>> jsonObject = JSON.parseObject(result, new TypeReference<ResponseDTO<List<RemindRecordsVO>>>() {
            });
            List<RemindRecordsVO> data = jsonObject.getData();
            data.forEach(e -> {
                com.zmn.oms.model.vo.work.CallRecordVO vo = com.zmn.oms.model.vo.work.CallRecordVO.builder().type(5).status(4)
                        .callRecordId(e.getRemindId()).callerNo(e.getLauncherStaffName()).calledNo(e.getTelPhone())
                        .connect(Objects.nonNull(e.getMtStartTime()) ? "是" : "否").answer(NumberUtil.isNotNullOrZero(e.getMtDuration()) ? "是" : "否")
                        .startTime(e.getMtStartTime()).finishTime(e.getMtEndTime()).callDuration(NumberUtil.isNotNullOrZero(e.getMtDuration()) ? TimeUtils.getDate(e.getMtDuration().intValue()) : "")
                        .hangupType(e.getByeUser()).finishType(e.getByeReason())
                        .tapeUrl(e.getTapeUrl()).build();
                switch (vo.getHangupType()) {
                    case 1:
                        vo.setHangup("用户挂断");
                        break;
                    case 2:
                        vo.setHangup("系统挂断");
                        break;
                }
                switch (vo.getFinishType()) {
                    case 1:
                        vo.setFinishState("正常");
                        break;
                    case 2:
                        vo.setFinishState("超时");
                        break;
                    case 3:
                        vo.setFinishState("异常");
                        break;
                    case 4:
                        vo.setFinishState("超出提醒时间段");
                        break;
                    case 5:
                        vo.setFinishState("黑名单用户");
                        break;
                }
                voList.add(vo);
            });
        } catch (Exception e) {
            log.error("通过http接口获取催单通话记录失败：", e);
        }
        return voList;
    }

    /**
     * 从云呼叫查询催单通话记录
     *
     * @param orderId
     * @return
     */
    private List<com.zmn.oms.model.vo.work.CallRecordVO> queryRemindRecordsFromCC(Long orderId) {
        List<com.zmn.oms.model.vo.work.CallRecordVO> voList = Lists.newArrayList();
        try {
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
            String month = DateUtil.dateFormatToString(orderWork.getReceiveTime(), DateUtil.FORMAT_MONTH2);
            log.info("#CallRecordBServiceImpl#queryRemindRecordsByCC 入参: orderId={},month={}", orderId, month);
            ResponseDTO<List<BizRecordDRO>> responseDTO = recordListRemoteService.listRecordByBizIdAndDate(String.valueOf(orderId), month);
            log.info("#CallRecordBServiceImpl#queryRemindRecordsByCC 出参: orderId={},responseDTO={}", orderId, JSON.toJSONString(responseDTO));
            List<BizRecordDRO> bizRecordDROList = responseDTO.getData();
            if (!responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(bizRecordDROList)) {
                return voList;
            }
            bizRecordDROList.forEach(bizRecordDRO -> {
                try {
                    com.zmn.oms.model.vo.work.CallRecordVO vo = com.zmn.oms.model.vo.work.CallRecordVO.builder()
                            .type(7).status(4).callRecordId(String.valueOf(bizRecordDRO.getRecordId()))
                            .callerNo(bizRecordDRO.getLine()).calledNo(bizRecordDRO.getPhone())
                            .connect(bizRecordDRO.getConnect() ? "是" : "否")
                            .answer(bizRecordDRO.getAnswer() ? "是" : "否")
                            .startTime(bizRecordDRO.getStartTime()).finishTime(bizRecordDRO.getEndTime())
                            .callDuration(NumberUtil.isNotNullOrZero(bizRecordDRO.getPhoneDuration()) ? TimeUtils.getDate(bizRecordDRO.getPhoneDuration().intValue()) : "")
                            .hangupType(bizRecordDRO.getByeWay().getCode())
                            .hangup(bizRecordDRO.getByeWay().getText())
                            .typeName(bizRecordDRO.getScenesType().getText())
                            .build();
                    voList.add(vo);
                } catch (Exception e) {
                    log.error("处理催单通话记录失败：", e);
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            log.error("从云呼叫查询催单通话记录失败：", e);
        }
        return voList;
    }
}
